﻿#******************************************************************************************************************************
# SPPackager.SPDeploy- Perform the instalation, upgrade and retraction of Ms Sharepoint Applications fast, easy and efficient
# Script version 6.0 - Aug, 15th of 2013
# Frederico Souza Lima (fredericosl@hotmail.com)
# Michael Capela (michaelcapela@hotmail.com)
# Copyright (c) 2012-2013 
#******************************************************************************************************************************

#******************************************************************************************************************************
# Powershell Global Parameters Definition
#******************************************************************************************************************************
If ($Host.Name -eq "PowerGUIScriptEditorHost") { cls; }
$ErrorActionPreference = "Stop";
$RawUI = (Get-Host).UI.RawUI;
$RawUI.BackgroundColor = "Black";
$RawUI.ForegroundColor = "White";

#******************************************************************************************************************************
# Load Microsoft Sharepoint Snapin
#******************************************************************************************************************************

if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
    Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}

#******************************************************************************************************************************
# Load .Net Assemblies used by functions
#******************************************************************************************************************************

[void][System.Reflection.Assembly]::LoadWithPartialName("System")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Xml")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Collections")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Collections.Generic");
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration")

#******************************************************************************************************************************
# Define Global Constants
#******************************************************************************************************************************

function ItemExistsByName([string]$SiteUrl, [string]$ListTitle, [string]$FolderRelativePath, [string]$Name)
{
	[Microsoft.SharePoint.SPWeb] $SPWeb = Get-SPWeb $SiteUrl;
	[Microsoft.SharePoint.SPList] $SPList = $SPWeb.Lists[$ListTitle];
	[Microsoft.SharePoint.SPFolder] $SPFolder = $SPWeb.GetFolder($SPList.RootFolder.ServerRelativeUrl + $FolderRelativePath);
	
	$SPQuery = New-Object Microsoft.SharePoint.SPQuery;
	$SPQuery.Folder = $SPFolder;
	$SPQuery.Query = "<Where><Eq><FieldRef Name='FileLeafRef' /><Value Type='Text'>$Name</Value></Eq></Where>";

	$SPListItemCollection = $SPList.GetItems($SPQuery);
	
	if ($SPListItemCollection.Count -gt 0) {
		$return = $true;
	}
	else {
		$return = $false;
	}
	
	$SPWeb.Close();
	$SPWeb.Dispose();
	
	return $return;

}

function ItemExistsByTitle([string]$SiteUrl, [string]$ListTitle, [string]$FolderRelativePath, [string]$Title)
{
	$SPWeb = Get-SPWeb $SiteUrl;
	$SPList = $SPWeb.Lists[$ListTitle];
	$SPFolder = $SPWeb.GetFolder($SPList.RootFolder.ServerRelativeUrl + $FolderRelativePath);
	
	$SPQuery = New-Object Microsoft.SharePoint.SPQuery;
	$SPQuery.Folder = $SPFolder;
	$SPQuery = New-Object Microsoft.SharePoint.SPQuery;
	$SPQuery.Query = "<Where><Eq><FieldRef Name='Title'/><Value Type='Text'>$Title</Value></Eq></Where>";

	$SPListItemCollection = $SPList.GetItems($SPQuery);
	
	if ($SPListItemCollection.Count -gt 0) {
		$return = $true;
	}
	else {
		$return = $false;
	}
	
	$SPWeb.Close();
	$SPWeb.Dispose();
	
	return $return;
}
function GetLookupValueByMultipleFields([string]$SiteUrl, [string]$ListTitle, [string]$FolderRelativePath, [string]$Title, [string]$FieldValues)
{
	$SPWeb = Get-SPWeb $SiteUrl;
	$SPList = $SPWeb.Lists[$ListTitle];
	$SPFolder = $SPWeb.GetFolder($SPList.RootFolder.ServerRelativeUrl + $FolderRelativePath);	
	$FieldKeyValue = $FieldValues.Split(";");
	
	[string] $andClause = "{1}<Eq><FieldRef Name='{3}'/><Value Type='{4}'>{0}</Value></Eq>{2}";
    [string] $whereClause = [string]::Empty;
	$whereClause = [string]::Format($andClause, $Title, "{1}", "{0}{2}", "Title", "Text");
	
	#LookupFieldNotUnique1="ListTitle#ItemTitle1|FieldName1#Value1;FieldName2#value1;...;FieldNameN#ValueN"
	for($i=0;$i -lt $FieldKeyValue.Length;$i++){
 			
			$FieldKey = $FieldKeyValue[$i].Split("#")[0];
			$FieldValue = $FieldKeyValue[$i].Split("#")[1];
			
            if (($FieldKeyValue.Length -eq 1) -or (($FieldKeyValue.Length -gt 1) -and ($i -eq $FieldKeyValue.Length - 1)))#first or last of any
            {
                $whereClause = [string]::Format($whereClause,
                [string]::Format($andClause, $FieldValue, [string]::Empty, [string]::Empty, $FieldKey, "Text"),
                "<Where><And>", "</And></Where>");
            }
            elseif (($FieldKeyValue.Length -gt 1) -and ($i -lt $FieldKeyValue.Length - 1))#intermediate of any
            {
                $whereClause = [string]::Format($whereClause,
                    [string]::Format($andClause, $FieldValue, [string]::Empty, [string]::Empty, $FieldKey, "Text"),
                    "{1}<And>", "</And>{0}{2}");
            }
            else
            {
                $whereClause = [string]::Format($andClause, $FieldValue, "<Where>", "</Where>", $FieldKey, "Text");#undefined
            }
	}
	
	
	[Microsoft.SharePoint.SPFieldLookupValue] $SPFieldLookupValue = $null;

	$SPQuery = New-Object Microsoft.SharePoint.SPQuery;
	$SPQuery.Folder = $SPFolder;
	$SPQuery = New-Object Microsoft.SharePoint.SPQuery;
	$SPQuery.Query = $whereClause;
	$SPQuery.RowLimit = 1;
	$SPQuery.ViewAttributes = 'Scope="RecursiveAll"';
	$SPListItemCollection = $SPList.GetItems($SPQuery);
	
	if ($SPListItemCollection.Count -eq 1) {

		$SPListItem = $SPListItemCollection[0];
		$SPFieldLookupValue =   New-Object Microsoft.SharePoint.SPFieldLookupValue($SPListItem.ID, $SPListItem.Title);
	}	
	
	$SPWeb.Close();
	$SPWeb.Dispose();
	
	return $SPFieldLookupValue;
}

function GetLookupValueByTitle([string]$SiteUrl, [string]$ListTitle, [string]$FolderRelativePath, [string]$Title)
{
	$SPWeb = Get-SPWeb $SiteUrl;
	$SPList = $SPWeb.Lists[$ListTitle];
	$SPFolder = $SPWeb.GetFolder($SPList.RootFolder.ServerRelativeUrl + $FolderRelativePath);
	
	[Microsoft.SharePoint.SPFieldLookupValue] $SPFieldLookupValue = $null;

	$SPQuery = New-Object Microsoft.SharePoint.SPQuery;
	$SPQuery.Folder = $SPFolder;
	$SPQuery = New-Object Microsoft.SharePoint.SPQuery;
	$SPQuery.Query = "<Where><Eq><FieldRef Name='Title'/><Value Type='Text'>$Title</Value></Eq></Where>";

	$SPListItemCollection = $SPList.GetItems($SPQuery);
	
	if ($SPListItemCollection.Count -eq 1) {

		$SPListItem = $SPListItemCollection[0];
		$SPFieldLookupValue =   New-Object Microsoft.SharePoint.SPFieldLookupValue($SPListItem.ID, $SPListItem.Title);
	}	
	
	$SPWeb.Close();
	$SPWeb.Dispose();
	
	return $SPFieldLookupValue;
}

function GetLookupValueByID([string]$SiteUrl, [string]$ListTitle, [string]$ID)
{
	$SPWeb = Get-SPWeb $SiteUrl;
	$SPList = $SPWeb.Lists[$ListTitle];

	[Microsoft.SharePoint.SPFieldLookupValue] $SPFieldLookupValue = $null;

	$SPQuery = New-Object Microsoft.SharePoint.SPQuery;
	$SPQuery.ViewAttributes = "Scope='RecursiveAll'";
	$SPQuery.Query = "<Where><Eq><FieldRef Name='ID'/><Value Type='Counter'>$ID</Value></Eq></Where>";

	$SPListItemCollection = $SPList.GetItems($SPQuery);
	
	if ($SPListItemCollection.Count -eq 1) {

		$SPListItem = $SPListItemCollection[0];
		$SPFieldLookupValue = New-Object Microsoft.SharePoint.SPFieldLookupValue($SPListItem.ID, $SPListItem.Title);
	}	
	
	$SPWeb.Close();
	$SPWeb.Dispose();
	
	return $SPFieldLookupValue;
}

$IsContentTypeFolder = @{};
function IsContentTypeFolder([string]$SiteUrl, [string]$ContentTypeName)
{
	$return = $false;
	
	if ($IsContentTypeFolder[$SiteUrl + $ContentTypeName] -eq $null) {
	
		$SPWeb = Get-SPWeb $SiteUrl;
		
		foreach($SPContentType in $SPWeb.ContentTypes)
		{
			if ($SPContentType.Name -eq $ContentTypeName)
			{
				if ($SPContentType.Id.ToString().startsWith("0x012") -eq $true) {
					$return = $true;
				}
				break;
			}
		}
		
		$SPWeb.Close();
		$SPWeb.Dispose();
		
		$IsContentTypeFolder.add($SiteUrl + $ContentTypeName, $return);
	}
	else {

		$return = $IsContentTypeFolder[$SiteUrl + $ContentTypeName];
	}
	
	return $return;
}


function ItemExistsByID([string]$SiteUrl, [string]$ListTitle, [string]$ID)
{
	$SPWeb = Get-SPWeb $SiteUrl;
	$SPList = $SPWeb.Lists[$ListTitle];

	$SPQuery = New-Object Microsoft.SharePoint.SPQuery;
	$SPQuery.ViewAttributes = "Scope='RecursiveAll'";
	$SPQuery.Query = "<Where><Eq><FieldRef Name='ID'/><Value Type='Counter'>$ID</Value></Eq></Where>";

	$SPListItemCollection = $SPList.GetItems($SPQuery);
	
	if ($SPListItemCollection.Count -gt 0) {
		$return = $true;
	}
	else {
		$return = $false;
	}
	
	$SPWeb.Close();
	$SPWeb.Dispose();
	
	return $return;
}

function AddItem([string]$SiteUrl, [string]$ListTitle, [string]$FolderRelativePath, $Attributes)
{
	[Microsoft.SharePoint.SPWeb] $SPWeb = Get-SPWeb $SiteUrl;
	[Microsoft.SharePoint.SPList] $SPList = $SPWeb.Lists[$ListTitle];
	[Microsoft.SharePoint.SPFolder] $SPFolder = $SPWeb.GetFolder($SPList.RootFolder.ServerRelativeUrl + $FolderRelativePath);

	$SPListItem = $SPList.AddItem($SPFolder.ServerRelativeUrl,[Microsoft.SharePoint.SPFileSystemObjectType]::File);
	
	if ($Attributes -ne $null) {
		SetAtributes $SPListItem $Attributes;
	}
	
	$SPListItem.SystemUpdate($false); 

	$SPWeb.Close();
	$SPWeb.Dispose();

}

function AddFile([string]$SiteUrl, [string]$ListTitle, [string]$FileName, [string]$FilePath, [string]$FolderRelativePath, $Attributes, [switch]$overwrite)
{
	[Microsoft.SharePoint.SPWeb] $SPWeb = Get-SPWeb $SiteUrl;
	[Microsoft.SharePoint.SPList] $SPList = $SPWeb.Lists[$ListTitle];
	[Microsoft.SharePoint.SPFolder] $SPFolder = $SPWeb.GetFolder($SPList.RootFolder.ServerRelativeUrl + $FolderRelativePath);
	[Microsoft.SharePoint.SPFileCollection] $SPFileCollection = $SPFolder.Files;
	[string] $FileRelativeUrl = $SPFolder.ServerRelativeUrl  + "/" + $FileName;

	[Microsoft.SharePoint.SPFile] $SPFile = $SPFileCollection.Add($FileRelativeUrl, $((Get-ChildItem $FilePath).OpenRead()), $overwrite);
	[Microsoft.SharePoint.SPListItem] $SPListItem = $SPFile.Item;

	if ($Attributes -ne $null) {
		SetAtributes $SPListItem $Attributes;
	}
	
	$SPListItem.SystemUpdate($false); 

	$SPWeb.Close();
	$SPWeb.Dispose();

}

function AddFolder([string]$SiteUrl, [string]$ListTitle, [string]$FolderRelativePath, [string]$Name, $Attributes)
{
	[Microsoft.SharePoint.SPWeb] $SPWeb = Get-SPWeb $SiteUrl;
	[Microsoft.SharePoint.SPList] $SPList = $SPWeb.Lists[$ListTitle];
	[Microsoft.SharePoint.SPFolder] $SPFolder = $SPWeb.GetFolder($SPList.RootFolder.ServerRelativeUrl + $FolderRelativePath);

	$SPListItem = $SPList.Items.Add($SPFolder.ServerRelativeUrl, [Microsoft.SharePoint.SPFileSystemObjectType]::Folder, $Name);
	
	if ($Attributes -ne $null) {
		SetAtributes $SPListItem $Attributes;
	}
	
	$SPListItem.SystemUpdate($false); 

	$SPWeb.Close();
	$SPWeb.Dispose();

}

function NetWorkUserOrGroupExists([string] $NetworkUserOrGroupLogin)
{
	$strDomain = $NetworkUserOrGroupLogin.substring(0,$NetworkUserOrGroupLogin.indexof("\"));
	$strUser = $NetworkUserOrGroupLogin.substring($NetworkUserOrGroupLogin.indexof("\") + 1);
	
	$objComputer = [ADSI]("WinNT://" + $strDomain)

	$colUsers = ($objComputer.psbase.children |
	    Where-Object {($_.AccountDisabled -eq $false) -and (($_.psBase.schemaClassName -eq "User") -or ($_.psBase.schemaClassName -eq "Group"))} |
	        Select-Object -expand Name)

	return $colUsers -contains $strUser;
}

function SetAtributes([Microsoft.SharePoint.SPListItem]$SPListItem, $Attributes)
{

	[Microsoft.SharePoint.SPList] $SPList = $SPListItem.ParentList;
	[Microsoft.SharePoint.SPWeb] $SPWeb = $SPList.ParentWeb;
	
	foreach ($Attribute in $Attributes.GetEnumerator())
	{
		$SPField = $SPList.Fields.TryGetFieldByStaticName($Attribute.Name);
		
		if ($SPField -ne $null) {
		
			switch ($SPField.TypeAsString) 
			{ 
				#http://msdn.microsoft.com/en-us/library/microsoft.SharePoint.spfieldtype(v=office.14).aspx
				"Boolean" {
						$SPListItem[$Attribute.Name] = [System.Convert]::ToBoolean($Attribute.Value);
					} 
				"Choice" {
						$SPListItem[$Attribute.Name] = $Attribute.Value;
					} 
				"Computed" {
						$SPListItem[$Attribute.Name] = $Attribute.Value;
					} 
				"Text" {
						$SPListItem[$Attribute.Name] = $Attribute.Value;
					} 
				"Lookup" {
						if($Attribute.Value.Contains("|") -eq $true){
							#LookupFieldNotUnique1="ListTitle#ItemTitle1||FieldName1;value1|FieldName2;value2|...|FieldNameN;ValueN"
							$LookupItemFieldValues = $Attribute.Value.Split("|")[1];							
							$LookupListTitle = $Attribute.Value.Split("|")[0].Split("#")[0];
							$LookupItemValue = $Attribute.Value.Split("|")[0].Split("#")[1];
							$SPListItem[$Attribute.Name] = GetLookupValueByMultipleFields $SPWeb.Site.Url $LookupListTitle "" $LookupItemValue $LookupItemFieldValues;												
						}
						else{
							$LookupListTitle = $Attribute.Value.Split("#")[0];
							$LookupItemValue = $Attribute.Value.Split("#")[1];
							$SPListItem[$Attribute.Name] = GetLookupValueByTitle $SPWeb.Site.Url $LookupListTitle "" $LookupItemValue;												
						}
						
					} 
				"Note" {
						$SPListItem[$Attribute.Name] = $Attribute.Value;
					} 
				"Number" {
						[Microsoft.SharePoint.SPFieldNumber] $SPFieldNumber = $SPField;
						$SPFieldNumber.ParseAndSetValue($SPListItem, $Attribute.Value);
					}
				"URL" {
						$RawValue = $Attribute.Value.Replace("{SiteCollectionURL}", $SPList.ParentWeb.Site.Url);
						$SPListItem[$Attribute.Name] = $RawValue;
					} 
				"User" {
						#if (NetWorkUserOrGroupExists $Attribute.Value){

							$SPUser = $SPWeb.EnsureUser($Attribute.Value);
							$SPFieldUserValue = New-Object Microsoft.SharePoint.SPFieldUserValue($SPWeb, $SPUser.ID, $SPUser.Name);					
							$SPListItem[$Attribute.Name] = $SPFieldUserValue;
						#}
						#else{
						#	$SPListItem[$Attribute.Name] = $null;
						#}						
					} 
			default {
				#throw  "The field $Attribute.Name with type $SPField.TypeAsString need to be developed...";
					$LookupListTitle = $Attribute.Value.Split("#")[0];
					$LookupItemValue = $Attribute.Value.Split("#")[1];
					[Microsoft.SharePoint.SPFieldLookupValue] $SPFieldLookupValue = $null;

						if($LookupItemValue.Contains(";") -eq $true){		

							[Microsoft.SharePoint.SPFieldMultiChoiceValue] $SPFieldMultiChoiceValue = New-Object Microsoft.SharePoint.SPFieldMultiChoiceValue;
							
							foreach ($ItemValue in $LookupItemValue.Split(";"))	{

								$SPFieldLookupValue = GetLookupValueByTitle $SPWeb.Site.Url $LookupListTitle "" $ItemValue;
								if($SPFieldLookupValue -ne $null){
									$SPFieldMultiChoiceValue.Add($SPFieldLookupValue.ToString());								
								}
							}

							#Write-Host $SPFieldMultiChoiceValue;
							#Write-Host $Attribute.Name;
							$SPListItem[$Attribute.Name] = $SPFieldMultiChoiceValue;
						}
						else {
						    $SPListItem[$Attribute.Name] = GetLookupValueByTitle $SPWeb.Site.Url $LookupListTitle "" $LookupItemValue;			
						}
				}
    		}			
		}
		else {
			throw  "The field $Attribute.Name doesn't exists in List...";
		}
	}
	
}

function GetAttributes([System.Xml.XmlElement]$XmlElement)
{
 	$return = @{};

	foreach ($XmlAttribute in $XmlElement.Attributes) {
		
		if (`
			($XmlAttribute.Name -ne "ID")`
			-and ($XmlAttribute.Name -ne "Name")`
			-and ($XmlAttribute.Name -ne "FolderRelativePath")`
			-and ($XmlAttribute.Name -ne "FilePath")`
			-and ($XmlAttribute.Name -ne "FileRelativePath")`
			-and ($XmlAttribute.Name -ne "Action")`
			-and ($XmlAttribute.Name -ne "ReplaceFileExtension")`
			) {
				$return.add($XmlAttribute.Name, $XmlAttribute.Value);
			}
	}
	
	if ($return.Count -gt 0) {
		return $return;
	}
	else {
		return $null;
	}
}

function ProcessChildrenNodes([Microsoft.SharePoint.Navigation.SPNavigationNodeCollection]$SPNavigationNodeCollection, [System.Xml.XmlElement]$NavigationNode)
{
	if ($NavigationNode.ChildrenNodes.Node -ne $null){
	
		foreach($Node in $NavigationNode.ChildrenNodes.Node) {
		
			$NodeType = $Node.Type;
			$NodeUrl = $Node.Url;
			$NodeTitle = $Node.Title;
			$NodeAction = $Node.Action;
			$NodeIsExternal = [System.Convert]::ToBoolean($Node.IsExternal);
			
			[Microsoft.SharePoint.Navigation.SPNavigationNode]$NewSPNode = $null;
			
			foreach ($SPNavigationNode in $SPNavigationNodeCollection)
			{
				if ($SPNavigationNode.Title -eq $NodeTitle) {
					$NewSPNode = $SPNavigationNode;
					break;
				}
			}
			
			if (($NewSPNode -ne $null) -and (($NodeAction -eq "Update") -or ($NodeAction -eq "InsertOrUpdate") -or ($NodeAction -eq "Delete"))){
				$SPNavigationNodeCollection.Delete($NewSPNode);				
			}

			if (($NewSPNode -eq $null) -or ($NodeAction -ne "Delete")){
				$NewSPNode = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode($NodeTitle, $NodeUrl, $NodeIsExternal);
				$SPNavigationNodeCollection.AddAsLast($NewSPNode) | out-null;
				
				$NewSPNode = $SPNavigationNodeCollection[$SPNavigationNodeCollection.Count - 1];
				if ($NewSPNode.Properties.ContainsKey("Target")) {
					$NewSPNode.Properties.Remove("Target");
				}
				if($NodeIsExternal){
					$NewSPNode.Properties.Add("Target", "_blank");
				}
				else{
					$NewSPNode.Properties.Add("Target", "_self");
				}
				$NewSPNode.Properties["NodeType"] = $Node.Type;
				
				$NewSPNode.Update();

			}
			
			Write-Host "$NodeType Node $NodeTitle was $NodeAction..." 

			if ($Node.ChildrenNodes.Node -ne $null){
				ProcessChildrenNodes $NewSPNode.Children $Node;
			}
		
		}
	}
	
}


function ProcessNavigationNode([string] $SiteUrl, [System.Xml.XmlElement]$NavigationNode, [string]$NavigationType )
{

	[Microsoft.SharePoint.SPWeb] $SPWeb = Get-SPWeb $SiteUrl;
	[Microsoft.SharePoint.Publishing.PublishingWeb] $PublishingWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($SPWeb);
	
	[Microsoft.SharePoint.Navigation.SPNavigationNodeCollection] $SPNavigationNodeCollection = $null;
	
	switch ($NavigationType) 
	{ 
		"Global" {
			$SPNavigationNodeCollection = $PublishingWeb.Navigation.GlobalNavigationNodes;
		} 
		"Current" {
			$SPNavigationNodeCollection = $PublishingWeb.Navigation.CurrentNavigationNodes;
		} 
		"TopNavigation" {
			$SPNavigationNodeCollection = $SPWeb.Navigation.TopNavigationBar;
		} 
		"QuickLaunch" {
			$SPNavigationNodeCollection = $SPWeb.Navigation.QuickLaunch;
		} 
	}
	
	ProcessChildrenNodes $SPNavigationNodeCollection $NavigationNode;
	
	$PublishingWeb.Update();
	
	$SPWeb.Close();
	$SPWeb.Dispose();
}

#******************************************************************************************************************************
# Load Deploy Settings
#****************************************************************************************************************************************

$MyPath = Split-Path $MyInvocation.MyCommand.Path
cd $MyPath;
$DeployXML = [xml] (Get-Content ($args[0]) -Encoding UTF8);
$HostedApplicationsXML = [xml] (Get-Content ("HostedApplications.xml") -Encoding UTF8);

$WebApplications = $DeployXML.Deploy.WebApplications.WebApplication;
$HostedApplications = $HostedApplicationsXML.Deploy.HostedApplications.ComputerHost;

#****************************************************************************************************************************************
# Process Web Applications
#******************************************************************************************************************************

if ($WebApplications -ne $null){

	foreach($WebApplication in $WebApplications) {

		$WebApplicationName =  $WebApplication.Name;
		$hostname = hostname;
		
 		foreach($ComputerHost in $HostedApplications) {
		
			$ComputerHostName = $ComputerHost.ComputerName;
			
			if ($ComputerHostName.toString().toLower() -eq $hostname.toString().toLower()) {
			
				foreach($HostWebApplication in $ComputerHost.WebApplications.WebApplication) {
				
					$HostWebApplicationName =  $HostWebApplication.Name;
					$HostWebApplicationURL =  $HostWebApplication.URL;
							
					if ($HostWebApplicationName -eq $WebApplicationName) {
					
						If ($HostWebApplicationURL.toString().EndsWith("/")){
							$WebApplicationURL =  $HostWebApplicationURL.toString().Substring(0, $HostWebApplicationURL.toString().Length-1);
						}
						else {
							$WebApplicationURL = $HostWebApplicationURL;
						}
		
						break;
					}
				}
				
				break;
			}
		}

#******************************************************************************************************************************
# Process WebApplication Site Collections
#******************************************************************************************************************************

		foreach($SiteCollection in $WebApplication.SiteCollections.SiteCollection) {

			if (([System.String]::IsNullOrEmpty($SiteCollection.Name) -eq $false) -and ($SiteCollection.Name -ne "SiteCollection")) {
				$SiteCollectionName =  $SiteCollection.Name;
			} else { $SiteCollectionName = $null;}
			
			foreach($HostSiteCollection in $HostWebApplication.SiteCollections.SiteCollection) {
			
				$HostSiteCollectionName =  $HostSiteCollection.Name;
				$HostSiteCollectionManagedPathUrl =  $HostSiteCollection.ManagedPathUrl;
				$HostSiteCollectionURL =  $HostSiteCollection.URL;
						
				if ($HostSiteCollectionName -eq $SiteCollectionName) {
				
					$SiteCollectionURL =  $WebApplicationURL + $HostSiteCollectionManagedPathUrl + $HostSiteCollectionURL;
					$SiteCollectionManagedPathUrl = $HostSiteCollectionManagedPathUrl;
					break;
				}
			}
			
#******************************************************************************************************************************
# Process Site Collection Navigation
#******************************************************************************************************************************
		if ($SiteCollection.NavigationNodes.NavigationNode -ne $null){
		
				Write-Host "Processing Navigation Nodes for Site $SiteCollectionURL..." 
		
				foreach($NavigationNode in $SiteCollection.NavigationNodes.NavigationNode) {
					$NavigationNodeType = $NavigationNode.Type;
					ProcessNavigationNode $SiteCollectionURL $NavigationNode $NavigationNodeType;
				}
			}
					
#******************************************************************************************************************************
# Process Site Collection Lists
#******************************************************************************************************************************
			if ($SiteCollection.Lists.List -ne $null){
			
				Write-Host "Processing Lists for Site $SiteCollectionURL..." 
			
				foreach($List in $SiteCollection.Lists.List) {
					
					$ListTitle = $List.Title
					Write-Host "Processing Rows for List $ListTitle..." 
					
#******************************************************************************************************************************
# Process List Rows
#******************************************************************************************************************************

					if ($List.Rows.Row -ne $null){
						foreach($Row in $List.Rows.Row) {
							
							$RowAction = $Row.Action
							
							$RowID = $Row.ID;
							$RowTitle = $Row.Title;
							$RowName = $Row.Name;
							$RowFileExtension = $Row.ReplaceFileExtension;														
							$RowFilePath = $Row.FilePath;
							$RowFileRelativePath = $Row.FileRelativePath;
							
							$RowFolderRelativePath = $Row.FolderRelativePath; if ([System.String]::IsNullOrEmpty($RowFolderRelativePath) -eq $true) {$RowFolderRelativePath="/";}
							$RowContentType = $Row.ContentType;
														
							if ($RowAction -eq "Delete") {
								Write-Host "Delete To be developed..." 
							} elseif ($RowAction -eq "Insert") {

								
								if (([System.String]::IsNullOrEmpty($RowFilePath) -eq $false) -or (([System.String]::IsNullOrEmpty($RowFileRelativePath)) -eq $false)) {
									# File Row
									if ([System.String]::IsNullOrEmpty($RowFilePath) -eq $true) {
										$RowFilePath = $MyPath + $RowFileRelativePath;
									}
									if ([System.String]::IsNullOrEmpty($RowName) -eq $true) {
										$RowName = $RowFilePath.Substring($RowFilePath.LastIndexOf("\")+1);
									}
									#MSOCAF DOES NOT ALLOW EXCEL EXTENTION
									if ([System.String]::IsNullOrEmpty($RowFileExtension) -eq $true) {
											$RowName = $RowName.Replace($RowName.Substring($RowName.LastIndexOf(".")),$RowFileExtension);
										}
									if ((ItemExistsByName $SiteCollectionURL $ListTitle $RowFolderRelativePath $RowName) -eq $false) {
										$RowAttributes = GetAttributes $Row;										
										AddFile $SiteCollectionURL $ListTitle $RowName $RowFilePath $RowFolderRelativePath $RowAttributes $false;
										Write-Host "File $RowFilePath was inserted..." 
									}
								}
								else {
									# Item Row
									$CanInsert = $false;
									
									if (([System.String]::IsNullOrEmpty($RowContentType) -eq $true) -or ((IsContentTypeFolder $SiteCollectionURL $RowContentType) -eq $false)) {
										# Listitem Row
										if ([System.String]::IsNullOrEmpty($RowID) -eq $false) {
											if ((ItemExistsByID $SiteCollectionURL $ListTitle $RowID) -eq $false) {
												$CanInsert = $true;
											}
										}
										elseif ([System.String]::IsNullOrEmpty($RowTitle) -eq $false) {
											#if(($List.TitleUnique -ne $null) -and [System.Boolean]$List.TitleUnique -eq $false)
											#{
												$CanInsert = $true;
											#}
											#elseif ((ItemExistsByTitle $SiteCollectionURL $ListTitle $RowFolderRelativePath $RowTitle) -eq $false) {
											#	$CanInsert = $true;
											#}
										}
										
										if ($CanInsert -eq $true) {
											$RowAttributes = GetAttributes $Row;
											AddItem $SiteCollectionURL $ListTitle $RowFolderRelativePath $RowAttributes;
											Write-Host "Item $RowID $RowTitle was inserted..." 
										}
									}
									else {
										# FolderItem Row
										if ([System.String]::IsNullOrEmpty($RowID) -eq $false) {
											if ((ItemExistsByID $SiteCollectionURL $ListTitle $RowID) -eq $false) {
												$CanInsert = $true;
											}
										}
										elseif ([System.String]::IsNullOrEmpty($RowName) -eq $false) {
											if ((ItemExistsByName $SiteCollectionURL $ListTitle $RowFolderRelativePath $RowName) -eq $false) {
												$CanInsert = $true;
											}
										}
										
										if ($CanInsert -eq $true) {
											$RowAttributes = GetAttributes $Row;
											AddFolder $SiteCollectionURL $ListTitle $RowFolderRelativePath $RowName $RowAttributes;
											Write-Host "Folder $RowName ($RowID) was inserted..." 
										}
									}
								}
								
							} elseif ($RowAction -eq "InsertOrUpdate") {
								Write-Host "InsertOrUpdate To be developed..." 
							} elseif ($RowAction -eq "Update") {
								Write-Host "Update To be developed..." 
							} else {
								Write-Host "Action doesn't exists..." 
							}
						}
					}
					
				}
			}
		}
	}	
}


			
